# -*- coding: utf-8 -*-
# Gestión de imports de módulo.

## vipera, un diseñador de aplicaciones para Python
##     Copyright (C) 2011 Ángel Luis García García
##
##    This program is free software: you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation, either version 3 of the License, or
##    (at your option) any later version.
##
##    This program is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.
##
##    You should have received a copy of the GNU General Public License
##    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import wx

from imports_vista import panel_import
from i18n_vipera import t

class dialogo(wx.Dialog):
    '''Clase para diálogo de menús'''
    def __init__(self, parent, opcion = 0, idioma = None):
        '''Constructor de clase'''
        # Definimos parámetros.
        if opcion == 0: titulo = 'import'
        if opcion == 1: titulo = 'from ... import ...'
        wx.Dialog.__init__(self, parent, title = titulo,style=wx.DEFAULT_DIALOG_STYLE)
        # Sizer principal.
        sizer = wx.BoxSizer(wx.VERTICAL)
        # Primer elemento.
        # Si estamos creando imports, no hay from.
        if opcion == 1: 
            box = wx.BoxSizer(wx.HORIZONTAL)
            label = wx.StaticText(self, -1, "from")
            box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
            self.text_from = wx.TextCtrl(self, -1, "", size=(80,-1))
            self.text_from.SetFocus()
            box.Add(self.text_from, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
            sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        # Segundo elemento.
        box = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, -1, "import")
        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.text_import = wx.TextCtrl(self, -1, "", size=(80,-1))
        box.Add(self.text_import, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
        sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        # Si estamos creando imports, el foco para el import.
        if opcion == 0: self.text_import.SetFocus()
        # Tercer elemento.
        box = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, -1, "as")
        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
        self.text_as = wx.TextCtrl(self, -1, "", size=(80,-1))
        box.Add(self.text_as, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
        sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        # Línea de separación y botones.
        line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
        sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
        btnsizer = wx.StdDialogButtonSizer()
        btn = wx.Button(self, wx.ID_OK)
        btn.SetDefault()
        btnsizer.AddButton(btn)
        btn = wx.Button(self, wx.ID_CANCEL)
        btnsizer.AddButton(btn)
        btnsizer.Realize()
        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)

class panel_import_p(panel_import):
    '''Panel de imports de módulo'''
    def __init__(self, parent, idioma = None):
        '''Constructor de clase'''
        panel_import.__init__(self, parent)
        # Idioma.
        self.l = idioma
        # Creamos columnas.
        self.m_listCtrl_from.InsertColumn(0,u"from x import y as z")
        self.m_listCtrl_import.InsertColumn(0,u"import x as z")
        self.m_listCtrl_from.SetColumnWidth(0, 500)
        self.m_listCtrl_import.SetColumnWidth(0, 500)
        # Binding.
        self.m_panel_import.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
        self.m_panel_from.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
        
    def limpiar_widget(self):
        '''Limpiar widgets'''
        self.m_listCtrl_from.DeleteAllItems()
        self.m_listCtrl_import.DeleteAllItems()
        
    def OnContextMenu(self, event):
        '''Menú contextual'''
        # Crear elemento.
        self.id_crear = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnCrear, id=self.id_crear)
        # Modificar elemento.
        self.id_modificar = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnModificar, id=self.id_modificar)
        # Eliminar elemento.
        self.id_eliminar = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnEliminar, id=self.id_eliminar)
        # Subir un elemento en lo más alto.
        self.id_subir = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnSubir, id=self.id_subir)
        # Bajar un elemento en lo más bajo.
        self.id_bajar = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnBajar, id=self.id_bajar)
        # Creamos un menú.
        menu = wx.Menu()
        # Elementos del menú.
        item_crear = wx.MenuItem(menu, self.id_crear,t(u"Crear", self.l))
        item_modificar = wx.MenuItem(menu, self.id_modificar, t(u"Modificar", self.l))
        item_eliminar = wx.MenuItem(menu, self.id_eliminar, t(u"Eliminar", self.l))
        item_subir = wx.MenuItem(menu, self.id_subir, t(u"Subir", self.l))
        item_bajar = wx.MenuItem(menu, self.id_bajar,t(u"Bajar", self.l))
        # Añadimos elementos al menú.
        menu.AppendItem(item_crear)
        menu.AppendItem(item_modificar)
        menu.AppendItem(item_eliminar)
        menu.AppendSeparator()
        menu.AppendItem(item_subir)
        menu.AppendItem(item_bajar)
        # Mostramos el PopMenu.
        self.PopupMenu(menu)
        # Cuando se quita el PopMenu se tiene que limpiar memoria.
        menu.Destroy()
        
    def __datos_imports(self, a, opcion = 0, elem_a_modif = None):
        '''Obtener e incluir datos de módulos en el panel'''
        # import módulo.
        t2 = a.text_import.GetValue()    
        t3 = a.text_as.GetValue()
        if self.m_notebook_import.GetSelection() == 1:
            # Obtenemos el from.
            t1 = a.text_from.GetValue()
            # Tiene que estar bien formado.
            if len(t1.strip()) == 0 or len(t2.strip()) == 0: return
            # Formamos cadena.
            cadena = 'from %s import %s' % (t1.strip(), t2.strip())
            if len(t3.strip()) !=0: cadena += ' as %s' % t3.strip()
            # Y lo incluimos en el control de lista.
            if opcion == 0:
                n = self.m_listCtrl_from.GetItemCount()
                self.m_listCtrl_from.InsertStringItem(n,cadena)
            if opcion == 1:
                self.m_listCtrl_from.SetStringItem(elem_a_modif, 0, cadena)
        if self.m_notebook_import.GetSelection() == 0:
            # Tiene que estar bien formado.
            if len(t2.strip()) == 0: return
            # Formamos cadena.
            cadena = 'import %s' % t2.strip()
            if len(t3.strip()) !=0: cadena += ' as %s' % t3.strip()
            # Y lo incluimos en el control de lista.
            if opcion == 0:
                n = self.m_listCtrl_import.GetItemCount()
                self.m_listCtrl_import.InsertStringItem(n,cadena)
            if opcion == 1:
                self.m_listCtrl_import.SetStringItem(elem_a_modif, 0, cadena)

    def __mover_item(self):
        '''Movimiento de elementos'''
        if self.m_notebook_import.GetSelection() == 0: 
            aux = self.m_listCtrl_import
        if self.m_notebook_import.GetSelection() == 1: 
            aux = self.m_listCtrl_from
        if aux.GetSelectedItemCount() > 1:
            wx.MessageBox(t(u"Seleccione solo un elemento a desplazar", self.l), t(u"Atención", self.l),wx.OK)
            return None
        # Obtenemos el elemento seleccionado.
        item_sel = aux.GetFirstSelected()
        if item_sel == -1: 
            return None
        else: 
            # Guardamos el valor.
            cadena = aux.GetItemText(item_sel)
            # Eliminamos el valor.
            aux.DeleteItem(item_sel)
            # Devolvemos el contenido del elemento.
            return cadena

    def OnSubir(self, event):
        '''Subir módulo'''
        # Obtenemos el elemento seleccionado.
        cadena = self.__mover_item()
        if cadena is None: return
        # Insertamos el elemento el primero.
        if self.m_notebook_import.GetSelection() == 0: 
            self.m_listCtrl_import.InsertStringItem(0,cadena)
        if self.m_notebook_import.GetSelection() == 1: 
            self.m_listCtrl_from.InsertStringItem(0,cadena)
        
    def OnBajar(self, event):
        '''Bajar módulo'''
        # Obtenemos el elemento seleccionado.
        cadena = self.__mover_item()
        if cadena is None: return
        # Insertamos el elemento el último.
        if self.m_notebook_import.GetSelection() == 0: 
            n = self.m_listCtrl_import.GetItemCount()    
            self.m_listCtrl_import.InsertStringItem(n,cadena)
        if self.m_notebook_import.GetSelection() == 1: 
            n = self.m_listCtrl_from.GetItemCount()    
            self.m_listCtrl_from.InsertStringItem(n,cadena)

    def OnCrear(self, event):
        '''Crear módulo'''
        if self.m_notebook_import.GetSelection() == 0: 
            a = dialogo(self, idioma = self.l)
        if self.m_notebook_import.GetSelection() == 1: 
            a = dialogo(self, 1, idioma = self.l)
        a.Show()
        if a.ShowModal() == wx.ID_OK: 
            self.__datos_imports(a)
        # Limpiamos memoria y nos vamos.
        a.Destroy()

    def OnModificar(self, event):
        '''Modificar módulo'''
        if self.m_notebook_import.GetSelection() == 0: 
            aux = self.m_listCtrl_import
            a = dialogo(self, idioma = self.l)
        if self.m_notebook_import.GetSelection() == 1: 
            aux = self.m_listCtrl_from
            a = dialogo(self, 1, idioma = self.l)
        if aux.GetSelectedItemCount() > 1:
            wx.MessageBox(t(u"Seleccione solo un elemento a modificar", self.l), t(u"Atención", self.l),wx.OK)
            a.Destroy()
            return
        # Obtenemos el elemento seleccionado. Si no hay nada seleccionado, nos vamos.
        item_sel = aux.GetFirstSelected()
        if item_sel == -1: 
            a.Destroy()
            return
        # Mostramos el diálogo.
        a.Show()
        if a.ShowModal() == wx.ID_OK: 
            self.__datos_imports(a, 1, item_sel)
        # Limpiamos memoria y nos vamos.
        a.Destroy()
        
    def OnEliminar(self, event):
        '''Eliminar módulo'''
        if self.m_notebook_import.GetSelection() == 0: 
            aux = self.m_listCtrl_import
        if self.m_notebook_import.GetSelection() == 1: 
            aux = self.m_listCtrl_from
        while True:
            x = aux.GetFirstSelected()
            aux.DeleteItem(x)
            if x == -1: break

    def salvar_datos(self):
        '''Método que recorre los imports y los devuelve en un diccionario'''        
        Import_From = self.m_listCtrl_from
        Import = self.m_listCtrl_import
        # Tratamos cada lista.
        lista_imp = list()
        n_imports = Import.GetItemCount()
        for i in range(n_imports):
            j = Import.GetItem(i).GetText()
            lista_imp.append(j)
        lista_imp_f = list()
        n_imports = Import_From.GetItemCount()
        for i in range(n_imports):
            j = Import_From.GetItem(i).GetText()
            lista_imp_f.append(j)
        # Creamos diccionario de imports.
        imports = {'import' : lista_imp,
                   'import_from' : lista_imp_f}    
        # Devolvemos diccionario.
        return imports

    def cargar_datos(self, dict_imports):
        '''Cargamos imports en widgets'''
        imports = dict_imports['import']
        imports_from = dict_imports['import_from']
        # Obtenemos referencias de los widget ListCtrl.
        Import_From = self.m_listCtrl_from
        Import = self.m_listCtrl_import
        # Tratamos cada lista.
        n_imports = len(imports)
        for j in range(n_imports):
            n = Import.GetItemCount()
            Import.InsertStringItem(n,imports[j])
        n_imports = len(imports_from)
        for j in range(n_imports):
            n = Import_From.GetItemCount()
            Import_From.InsertStringItem(n,imports_from[j])
    